package net.facelib.jni;

import static net.facelib.jni.BridgeLog.BRIDEG_LOGGER;
import static net.facelib.jni.DeviceSerialBridge.FSGetDevicesSerialMultiType;
import static net.facelib.jni.DeviceSerialBridge.FSGetFlashId;
import java.util.Arrays;
import java.util.Hashtable;

import net.facelib.akcore.AuthParameterProvider;
import net.facelib.akcore.BaseLicenseManager;
import net.facelib.authkernel.AuthKernelErrorType;
import net.facelib.authkernel.ServiceSecurityException;

/**
 * MTFSDK android/arm 授权信息管理对象基类 (akcore)
 * @author guyadong
 *
 */
public abstract class FacelibLicenseManager extends BaseLicenseManager {
	/** 保存设备列号  设备加密信息的类型(0,1)--序列号映射 */
	private final Hashtable<Integer,String> serials = new Hashtable<>();
	
	private volatile String flashid;
	
	public FacelibLicenseManager(String productId) {
		super(productId);
	}

	public FacelibLicenseManager(String productId, AuthParameterProvider defaultProvider) {
		super(productId, defaultProvider);
	}

	@Override
	public String getEncryptSerial(int ntype) throws ServiceSecurityException {
		String serial;
		// double check
		if(null == (serial = serials.get(ntype))){
			synchronized (serials) {
				if(null == (serial = serials.get(ntype))){
					try {
						byte[] buffer = new byte[129];
						// 输出缓冲区清0
						Arrays.fill(buffer, (byte)0);
						int res = FSGetDevicesSerialMultiType(buffer, "\0".getBytes(),ntype);
						BRIDEG_LOGGER.log("FSGetDevicesSerialMultiType ntype = {},res = {}",ntype,res);

						if (res <= 0) {
							throw new ServiceSecurityException(AuthKernelErrorType.FAIL_TO_GET_DEVICE_SERIAL);
						}
						serial = new String(buffer, 0, res);
						BRIDEG_LOGGER.log("FSGetDevicesSerialMultiType serial = {} for ntype {}", serial, ntype);
						serials.put(ntype, serial);
						return serial;
					} catch (RuntimeException e) {
						BRIDEG_LOGGER.log("{}:{}",e.getClass().getName(),e.getMessage());
						BRIDEG_LOGGER.logTrace(true, e);
						throw e;
					}
				}
			}
		}
		// 返回上次保存的序列号
		BRIDEG_LOGGER.log("CACHED serial = {} for ntype {}", serial, ntype);
		return serial;
	}

	@Override
	public String getPhysicalAddress() {
		// 懒加载方式获取硬件信息码,只调用FSGetFlashId一次
		// double check
		if(null == flashid){
			synchronized (this) {
				if(null == flashid){
					flashid = FSGetFlashId();
				}
			}
		}
		return flashid;
	}

}
